﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using SimpleOrmCFPC.Core.Model;
using SimpleOrmCFPC.Helpers;

namespace SimpleOrmCFPC.Core.Query.Select
{
    public class SelectComputer
    {


        public static List<string> ExtractSelects<U>()
        {
            return ExtractSelects(typeof (U), "");
        }

        private static List<string> ExtractSelects(Type type, string prefix)
        {
            var selects = new List<string>();
            foreach (var property in type.GetProperties())
            {
                if (property.HasAttribute<ManyToOneAttribute>())
                {
                    selects.AddRange(ExtractSelects(property.PropertyType, prefix + property.Name));
                }
                else
                {
                    selects.Add(string.Format("{0}.{1} as {2}", type.GetEntityName(), property.Name, prefix + property.Name));
                }
            }
            return selects;
        }

        public List<string> ComputeSelects<T, U>(Expression<Func<T, U>> proj)
        {
            if (proj.NodeType == ExpressionType.Lambda)
            {
                var lambda = (LambdaExpression)proj;
                var mem = lambda.Body as MemberExpression;
                if (mem != null && (mem.Expression.NodeType == ExpressionType.Parameter) && mem.Member is PropertyInfo)
                {
                    return new List<string>() {mem.Member.Name};
                }
                else
                {
                    var param = lambda.Body as ParameterExpression;
                    if (param != null && (param.NodeType == ExpressionType.Parameter))
                    {
                        return ExtractSelects<U>();
                    }
                    throw new NotSupportedException("select does not support: " + proj);
                }
            }
            else
            {
                throw new NotSupportedException("Must be a predicate");
            }
        }
    }
}
